const { isAsyncFunction } = require('util/types')
const _ = require('lodash')
const path = require('path')
const ProcessExecutor = require('./executor/process/ProcessExecutor')
const WorkerExecutor = require('./executor/worker/WorkerExecutor')
const Executor = require('./executor/Executor')
const ExecutorClient = require('./executor/ExecutorClient')

function requireObject(object, type, options) {
    const opts = {
        ttl: 60 * 1000,
        predicat: (_name, value) => _.isFunction(value) && isAsyncFunction(value),
        logPath: path.join(process.cwd(), 'logs'),
        logFile: 'executor',
        scriptPath: '',
        metedata: {}
    }
    _.merge(opts, options)
    let executor
    switch (type) {
        case 'Process':
            executor = new ProcessExecutor(opts)
            break
        case 'Worker':
            executor = new WorkerExecutor(opts)
            break
        default:
            throw new Error('不支持此执行器类型' + type)
    }
    opts.metedata.scriptPath = opts.scriptPath
    return executor.create(object, opts.predicat, opts.metedata)
}

function requireScript(script, type, options) {
    const object = require(script)
    options ||= {}
    options.scriptPath = options.scriptPath || script
    return requireObject(object, type, options)
}

module.exports = {
    Executor,
    ExecutorClient,
    ProcessExecutor,
    WorkerExecutor,
    requireScript,
    requireObject
}
